package com.ibiaoke.order.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.ibiaoke.common.base.Page;
import com.ibiaoke.common.configs.AliPayConfigs;
import com.ibiaoke.common.configs.GlobalConfigs;
import com.ibiaoke.common.configs.GlobalConfigsKey;
import com.ibiaoke.common.configs.WeChatConfigs;
import com.ibiaoke.common.consts.CommonConsts;
import com.ibiaoke.common.exception.ServiceException;
import com.ibiaoke.common.spring.ExceptionAspect;
import com.ibiaoke.common.utils.*;
import com.ibiaoke.customer.dao.CustomerDao;
import com.ibiaoke.customer.entity.Customer;
import com.ibiaoke.customer.entity.PtFightGroup;
import com.ibiaoke.customer.entity.PtOpenGroup;
import com.ibiaoke.customer.entity.ThirdPartLogin;
import com.ibiaoke.customer.service.DepositRecorderService;
import com.ibiaoke.customer.service.DepositService;
import com.ibiaoke.customer.service.FightGroupService;
import com.ibiaoke.customer.service.OpenGroupService;
import com.ibiaoke.goods.dao.PtGoodsDao;
import com.ibiaoke.goods.entity.PtGoods;
import com.ibiaoke.order.consts.PtOrderStatusConst;
import com.ibiaoke.order.dao.OrderAddressDao;
import com.ibiaoke.order.dao.PtOrderDao;
import com.ibiaoke.order.entity.OrderAddress;
import com.ibiaoke.order.entity.PtOrder;
import com.ibiaoke.order.entity.so.SubmitOrderSO;
import com.ibiaoke.system.dao.ShopDao;
import com.ibiaoke.system.entity.Shop;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.apache.poi.hssf.usermodel.*;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.net.ssl.SSLContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.security.KeyStore;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Service("ptOrderService")
public class PtOrderServiceImpl implements  PtOrderService{

    private static Logger logger = LoggerFactory.getLogger(ExceptionAspect.class);

    @Autowired
    private PtOrderDao ptOrderDao;

    @Autowired
    private PtGoodsDao ptGoodsDao;

    @Autowired
    private OpenGroupService openGroupService;

    @Autowired
    private OrderAddressService orderAddressService;

    @Autowired
    private FightGroupService fightGroupService;

    @Autowired
    private DepositService depositService;

    @Autowired
    private DepositRecorderService depositRecorderService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderAddressDao orderAddressDao;

    @Autowired
    private ShopDao shopDao;

    @Autowired
    private CustomerDao customerDao;

    @Override
    public List<PtOrder> getPtOrder(PtOrder ptOrder,Page page,String isEcxel) {
        if(ptOrder.getContactMobile() != null && !"".equals(ptOrder.getContactMobile())){
            Customer c  = customerDao.getByMobile(ptOrder.getContactMobile());
            if(c==null){
                throw new ServiceException("此用户不存在，请核实");
            }else{
                ptOrder.setUserId(c.getCustomerId());
            }
        }
        List<PtOrder> orderList = ptOrderDao.GetPtOrder(ptOrder,page,isEcxel);
        return orderList;
    }

    @Override
    public List<PtOrder> getPtOrderDeatil(String ptOrderCode) {
        List<PtOrder> orderList = ptOrderDao.getOrderDeatil(ptOrderCode);
        return orderList;
    }

    /**
     * 一键开团
     * @param customer
     * @param ptGoodsId
     * @param addressId
     * @param deliveryType
     * @return
     */
    @Override
    public PtOrder  submitPtGoodsOrder(Customer customer, Integer ptGoodsId, Integer addressId, Integer deliveryType,ThirdPartLogin thirdPartLogin,Integer shopId) {
        PtGoods ptgood = ptGoodsDao.selectByPrimaryKey(ptGoodsId);
        if(ptgood != null ){
            if(ptgood.getStatus() == 0){
                throw new ServiceException("此商品已下架");
            }
        }
        AssertUtils.notNull(customer,"请先登录");
        //存开团信息
        PtOpenGroup ptOpenGroup = new PtOpenGroup();
        ptOpenGroup.setUserId(customer.getCustomerId());
        ptOpenGroup.setOpenCode(orderService.generateOrderNo());
        ptOpenGroup.setIsOpen(CommonConsts.YES);
        ptOpenGroup.setPtGoodsId(ptGoodsId);
        ptOpenGroup.setStatus(CommonConsts.YES);
        ptOpenGroup.setIsPay(CommonConsts.NO);
        ptOpenGroup.setUserName(thirdPartLogin.getNickName());
        ptOpenGroup.setUserImg(thirdPartLogin.getHeadImageUrl());
        ptOpenGroup.setPtCount(ptgood.getPtType());
        ptOpenGroup.setCreateTime(new Date());
        ptOpenGroup.setUpdateTime(new Date());
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DATE,1);
        ptOpenGroup.setOverTime(c.getTime());
        PtOpenGroup ptOpenGroup1 = openGroupService.savePtOpenGroup(ptOpenGroup);
        //存订单信息
        PtOrder ptOrder = new PtOrder();
        ptOrder.setPtOrderCode(this.generateOrderNo());
        ptOrder.setUserId(customer.getCustomerId());
        ptOrder.setGoodId(ptGoodsId);
        ptOrder.setOpenCode(ptOpenGroup1.getOpenCode());
        ptOrder.setKid(ptOpenGroup1.getKid());
        ptOrder.setPtStatus(2);
        ptOrder.setOrderType(CommonConsts.YES);
        ptOrder.setIsopen(CommonConsts.YES);
        ptOrder.setIsdelete(CommonConsts.NO);
        ptOrder.setDeliveryType(deliveryType);
        if(ptOrder.getDeliveryType()==2){
            OrderAddress address = orderAddressDao.selectByPrimaryKey(addressId);
        //获取地址拼接
        ptOrder.setDeliveryAddress(address.toDetailAddress());
        ptOrder.setContactMobile(address.getContactPhone());
        ptOrder.setContactPersion(address.getContactName());
        }else if(ptOrder.getDeliveryType()==1){
            ptOrder.setShopId(shopId);
           Shop shop = shopDao.getShopByShopId(shopId);
           if(shop != null){
               ptOrder.setShopName(shop.getShopName());
           }
        }
        ptOrder.setCreateTime(new Date());
        ptOrder.setUpdateTime(new Date());
        ptOrder.setEndTime(c.getTime());
        ptOrderDao.savePtOrder(ptOrder);
        //更改商品剩余可开团数
        if(ptgood.getPtCount() > 0){
            ptGoodsDao.updatePtGoodsPtCount(ptgood,ptgood.getPtCount()-1);
        }
        return ptOrder;

    }

    //一键拼团
    @Override
    public PtOrder submitPtGoodsFlightOrder(SubmitOrderSO submitOrderSO,Integer ptGoodsId) {
        AssertUtils.notNull(submitOrderSO.getUserId(), "请先登录");
        //存拼团信息
        PtFightGroup ptFightGroup = new PtFightGroup();
        ptFightGroup.setUserId(submitOrderSO.getUserId());
        ptFightGroup.setPtGoodsId(ptGoodsId);
        ptFightGroup.setStatus(1);
        ptFightGroup.setUserName(submitOrderSO.getCustomerNickname());
        ptFightGroup.setUserImg(submitOrderSO.getUserNameImg());
        ptFightGroup.setKid(submitOrderSO.getKid());
        ptFightGroup.setCreateTime(new Date());
        ptFightGroup.setUpdateTime(new Date());
        List<PtOpenGroup>  ptOpenGroupList = openGroupService.getPtOpenGroup(submitOrderSO.getKid());
        if(ptOpenGroupList.get(0).getPtCount() == 0){
            throw new ServiceException("手慢一步，此团已经拼团成功");
        }
        ptFightGroup.setOverTime(ptOpenGroupList.get(0).getOverTime());
        PtFightGroup PtFightGroup = fightGroupService.saveFightGroup(ptFightGroup);
        //存订单信息
        PtOrder ptOrder = new PtOrder();
        ptOrder.setPtOrderCode(this.generateOrderNo());
        ptOrder.setUserId(submitOrderSO.getUserId());
        ptOrder.setGoodId(ptGoodsId);
        ptOrder.setKid(PtFightGroup.getPid());
        ptOrder.setPtStatus(2);
        ptOrder.setOrderType(2);
        ptOrder.setIsopen(0);
        ptOrder.setIsdelete(0);
        ptOrder.setDeliveryType(Integer.parseInt(submitOrderSO.getDeliveryType()));
        if(ptOrder.getDeliveryType()==2){
            OrderAddress address = orderAddressDao.selectByPrimaryKey(submitOrderSO.getAddressId());
            //获取地址拼接
            ptOrder.setDeliveryAddress(address.toDetailAddress());
            ptOrder.setContactMobile(address.getContactPhone());
            ptOrder.setContactPersion(address.getContactName());
        }
        ptOrder.setCreateTime(new Date());
        ptOrder.setUpdateTime(new Date());
        ptOrder.setEndTime(ptOpenGroupList.get(0).getOverTime());
        ptOrderDao.savePtOrder(ptOrder);
        return ptOrder;
}

    @Override
    public String generateOrderNo() {
        String dateNo = DateUtils.formatOrderNoDate(new Date());
        return dateNo + RandomUtils.generatorOrderNo();
    }

    @Override
    public List<PtOrder> getMyPtOrder(Integer userId,Page page) {
        return ptOrderDao.getMyPtOrder(userId,page);
    }

    @Override
    public Integer upPtOrderStatus(Integer orderId) {
        return ptOrderDao.upPtOrderStatus(orderId,5);
    }

    @Override
    public Integer removePtOrder(Integer orderId) {
        PtOrder ptOrder =ptOrderDao.GetPtOrderById(orderId);
        ptOrderDao.updatePtOrderIsDeteleStatus(orderId);
        return  openGroupService.deleteOpenGroup(ptOrder.getKid(),0);

    }

    @Override
    public PtOrder getPtOrderById(Integer orderId) {
        return ptOrderDao.GetPtOrderById(orderId);
    }

    @Override
    @Transactional
    public Integer updateOrderStatus(PtOrder ptOrder) {
        //更改openGroup的ispay为1
        openGroupService.updateIsPay(ptOrder.getKid(),1);
        PtOpenGroup PtOpenGroups = null;
        List<PtOpenGroup> ptOpenGroupList =  openGroupService.getPtOpenGroupListByOpenCode(ptOrder.getOpenCode());
        for(PtOpenGroup ptOpenGroupt : ptOpenGroupList){
            if(ptOpenGroupt.getIsOpen() == 1){
                PtOpenGroups = ptOpenGroupt;
                break;
            }
        }
        if(PtOpenGroups.getPtCount() == 1 || PtOpenGroups.getPtCount() == 0) {
            //更改所有order表的状态为1
            List<PtOrder> PtOrderList = ptOrderDao.getPtOrderByOpenCode(ptOrder.getOpenCode());
            for (PtOrder ptOrders : PtOrderList) {
                PtOpenGroup PtOpenGroups1 = openGroupService.getPtOpenGroupByKid(ptOrders.getKid());
                if(PtOpenGroups1.getIsPay() == 1){
                    ptOrderDao.upPtOrderStatus(ptOrders.getPtOrderId(), 1);
                    ptOrderDao.updateUpdateTime(ptOrders.getPtOrderId());
                }
            }
            //更改开团剩余数量
            if(PtOpenGroups.getPtCount() > 0 ){
                openGroupService.updatePtOpenGroupCount(PtOpenGroups.getKid(), PtOpenGroups.getPtCount() - 1);
            }
        }else{
            ptOrderDao.upPtOrderStatus(ptOrder.getPtOrderId(),4);
            if(PtOpenGroups.getPtCount() > 0 ){
                openGroupService.updatePtOpenGroupCount(PtOpenGroups.getKid(),PtOpenGroups.getPtCount()-1);
            }
        }
        ptGoodsDao.updatePtGoodSaleNum(PtOpenGroups.getPtGoodsId());
        return null;
    }

    @Override
    public Integer upPtOrderTransaction(Integer orderId, String TransactionNo) {
        return ptOrderDao.upPtOrderTransaction(orderId,TransactionNo);
    }

    @Override
    public void checkBeforPay(Integer orderId) {
        PtOrder ptOrder = ptOrderDao.GetPtOrderById(orderId);
        List<PtOpenGroup> ptOpenGroupList =  openGroupService.getPtOpenGroupListByOpenCode(ptOrder.getOpenCode());
        for(PtOpenGroup ptOpenGroupt : ptOpenGroupList){
            if(ptOpenGroupt.getIsOpen() == 1  && ptOpenGroupt.getPtCount() <= 0){
                throw new ServiceException("此商品已经拼团成功，请重试");
            }
        }
    }

    @Override
    public Integer UpdatePtOrder(PtOrder ptOrder) {
        return ptOrderDao.upPtOrder(ptOrder);
    }

    //72小时自动确认收货
    @Override
    @Transactional
    public void automaticReceipt() {
        //获取所有订单状态为1的订单
        List<PtOrder>  ptOrderList =  ptOrderDao.getPtOrderByStatus(1);
        //查询创建时间>72小时的订单，更改状态为5
        ptOrderDao.updateConfrimPtOrder(ptOrderList);
    }

    //超时，拼团失败，更改订单状态
    @Override
    public void updateOverTimePtOrder() {
        //获取所有订单状态为4的订单
        List<PtOrder>  ptOrderList =  ptOrderDao.getPtOrderByStatus(4);
        //查询创建时间>24小时的订单，更改状态为3
         ptOrderDao.updateOverTimePtOrder(ptOrderList);
    }

    @Override
    public void updatePtOrderStatusByCancel(Integer orderId) {
        ptOrderDao.upPtOrderStatus(orderId,7);
    }

    @Override
    public List<PtOrder> getPtOrderByCode(String ordercCode) {
        return ptOrderDao.getPtOrderByCode(ordercCode);
    }

    @Override
    public void updateWaitPayPtOrder() {
        ptOrderDao.updateWaitPayPtOrder();
    }

    @Override
    public Integer updateDelete(Integer orderId,Integer delete) {
        return ptOrderDao.updateDelete(orderId,delete);
    }

    /**
     * 未成团，退款
     */
    @Transactional
    @Override
    public void PtPayRefund() {
        /**
         * 获取所有订单状态为3的订单
         */
        List<PtOrder>  ptOrderList =  ptOrderDao.getPtOrderByStatus(3);
        //退款
        for(PtOrder ptOrder:ptOrderList){
            boolean judge = false;
            List<PtOpenGroup> ptOpenGroupList =  openGroupService.getPtOpenGroupListByOpenCode(ptOrder.getOpenCode());
            for(PtOpenGroup ptOpenGroupt : ptOpenGroupList){
                if(ptOpenGroupt.getIsOpen() == 1){
                     judge =  System.currentTimeMillis()>ptOpenGroupt.getOverTime().getTime();
                }
            }
            if(judge){
                if(ptOrder.getPayType()==1){
                    this.refundPay(ptOrder.getPtOrderId(),ptOrder.getPtOrderCode(),ptOrder.getTransactionNo(),Double.valueOf(ptOrder.getPrice().toString()));
                }else if(ptOrder.getPayType()==2){
                    this.alipayRefundRequest(ptOrder.getPtOrderCode(),ptOrder.getTransactionNo(),Double.valueOf(ptOrder.getPrice().doubleValue()));
                }else if(ptOrder.getPayType()==3){
                    //根据用户Id，更改（增加）可用预存款金额
                    depositService.updatePrice(ptOrder.getUserId(),ptOrder.getPrice());
                    //增加当前用户流水记录 表bk_deposit_recorder
                    depositRecorderService.insertByRefund(ptOrder.getUserId(),3,ptOrder.getPtOrderCode(),1,ptOrder.getPrice());
                    //修改订单状态为6
                    ptOrderDao.upPtOrderStatus(ptOrder.getPtOrderId(),6);
                    //发送短信
                    sendMsgRefund(ptOrder);
                }
            }
        }
    }

    @Override
    public PtOrder submitPtFlightOrder(SubmitOrderSO submitOrderSO, PtOpenGroup openGroup, Customer customer,ThirdPartLogin thirdPartLogin) {
        AssertUtils.notNull(customer.getCustomerId(), "用户Id不能为空");
        AssertUtils.notBlank(openGroup.getOpenCode(), "开团码不能为空");

        PtOpenGroup ValideOpenGroup = openGroupService.checkOpenGroup(openGroup.getOpenCode(),openGroup.getPtGoodsId(),customer.getCustomerId());
        if(ValideOpenGroup != null  &&  ValideOpenGroup.getIsPay() == 1 ){
                throw  new ServiceException("别闹！你已经在里面了!");
        }

        AssertUtils.requireTrue(openGroup.getPtCount() > 0, "你的手速慢了！");

        PtGoods ptgood = ptGoodsDao.selectByPrimaryKey(openGroup.getPtGoodsId());
        AssertUtils.notNull(ptgood,"拼团商品Id不存在，tan90°");

        //存开团信息
        PtOpenGroup ptOpenGroup = new PtOpenGroup();
        //拼团用户Id
        ptOpenGroup.setUserId(customer.getCustomerId());
        //开团码
        ptOpenGroup.setOpenCode(openGroup.getOpenCode());
        //拼团
        ptOpenGroup.setIsOpen(CommonConsts.NO);
        //商品Id
        ptOpenGroup.setPtGoodsId(openGroup.getPtGoodsId());
        //拼团状态
        ptOpenGroup.setStatus(CommonConsts.YES);
        //拼团未付款
        ptOpenGroup.setIsPay(CommonConsts.NO);
        //获取用户昵称
        ptOpenGroup.setUserName(thirdPartLogin.getNickName());
        //获取用户头像
        ptOpenGroup.setUserImg(thirdPartLogin.getHeadImageUrl());
        //开始 修改 结束 时间
        ptOpenGroup.setCreateTime(new Date());
        ptOpenGroup.setUpdateTime(new Date());
        ptOpenGroup.setOverTime(openGroup.getOverTime());

        PtOpenGroup ptOpenGroup1 = openGroupService.savePtOpenGroup(ptOpenGroup);



        //存订单信息
        PtOrder ptOrder = new PtOrder();
        ptOrder.setPtOrderCode(this.generateOrderNo());
        ptOrder.setUserId(customer.getCustomerId());
        ptOrder.setOpenCode(openGroup.getOpenCode());
        ptOrder.setGoodId(openGroup.getPtGoodsId());
        ptOrder.setKid(ptOpenGroup1.getKid());
        ptOrder.setPtStatus(PtOrderStatusConst.PAID);
        ptOrder.setOrderType(PtOrderStatusConst.PT_Order);
        ptOrder.setIsopen(CommonConsts.NO);
        ptOrder.setIsdelete(CommonConsts.NO);
        ptOrder.setDeliveryType(Integer.valueOf(submitOrderSO.getDeliveryType()));
        if("2".equals(submitOrderSO.getDeliveryType())){
            OrderAddress address = orderAddressDao.selectByPrimaryKey(submitOrderSO.getAddressId());
            ptOrder.setDeliveryAddress(address.toDetailAddress());
            ptOrder.setContactMobile(address.getContactPhone());
            ptOrder.setContactPersion(address.getContactName());
            /*OrderAddress orderAddress = orderAddressService.getOrderAddress(submitOrderSO.getAddressId());
            ptOrder.setDeliveryAddress(orderAddress.getDetailAddress());
            ptOrder.setContactMobile(orderAddress.getContactPhone());
            ptOrder.setContactPersion(orderAddress.getContactName());*/
        }else if("1".equals(submitOrderSO.getDeliveryType())){
            ptOrder.setShopId(submitOrderSO.getShopId());
            Shop shop = shopDao.getShopByShopId(submitOrderSO.getShopId());
            if(shop != null){
                ptOrder.setShopName(shop.getShopName());
            }
        }
        ptOrder.setCreateTime(new Date());
        ptOrder.setUpdateTime(new Date());
        ptOrder.setEndTime(openGroup.getOverTime());
        ptOrderDao.savePtOrder(ptOrder);
        return ptOrder;
    }

    @Transactional
    @Override
    public  Object refundPay(Integer orderId,String ptOrderCode,String transactionNo,double totalFee) {
        try{
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            FileInputStream instream = new FileInputStream(new File(this.getClass().getClassLoader().getResource(GlobalConfigs.getConfigure(GlobalConfigsKey.WeChat.pt_Refund_Certificate)).getPath()));
            try {
                keyStore.load(instream, WeChatConfigs.getMchID().toCharArray());
            }finally {
                instream.close();
            }
            SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, WeChatConfigs.getMchID().toCharArray()).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
            HttpPost httppost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");
            String xml =wxPayRefund(ptOrderCode,transactionNo,String.valueOf((int)(totalFee*100)));

            try {
                StringEntity se = new StringEntity(xml);
                httppost.setEntity(se);
                CloseableHttpResponse responseEntry = httpclient.execute(httppost);
                try {
                    HttpEntity entity = responseEntry.getEntity();
                    if (entity != null) {
                        JSONObject result = new JSONObject();
                        SAXReader saxReader = new SAXReader();
                        Document document = saxReader.read(entity.getContent());
                        Element rootElt = document.getRootElement();
                        String resultcode ="";
                        String return_msg = rootElt.elementText("return_msg");
                        String err_code = rootElt.elementText("err_code");
                        String err_code_des = rootElt.elementText("err_code_des");
                        String return_code = rootElt.elementText("return_code");
                        resultcode = rootElt.elementText("result_code");
                        if(resultcode.equals("SUCCESS")){
                            result.put("weixinPayUrl", rootElt.elementText("code_url"));
                            result.put("prepayId", rootElt.elementText("prepay_id"));
                            result.put("status","success");
                            result.put("msg","success");
                            //成功，更改订单状态
                            ptOrderDao.upPtOrderStatus(orderId,6);
                            //发送短信
                            sendMsgRefund(ptOrderDao.GetPtOrderById(orderId));
                        }else{
                            result.put("status","false");
                            result.put("msg",rootElt.elementText("err_code_des"));
                        }
                        return result;
                    }
                    EntityUtils.consume(entity);
                }
                finally {
                    responseEntry.close();
                }
            }
            finally {
                httpclient.close();
            }
            return null;
        }catch(Exception e){
            e.printStackTrace();
            JSONObject result = new JSONObject();
            result.put("status","error");
            result.put("msg",e.getMessage());
            return result;
        }
    }
    public  String wxPayRefund(String out_trade_no, String transaction_id,String total_fee) {
        StringBuffer xml = new StringBuffer();
        String data = null;
        try {
            String nonceStr = this.generateOrderNo();//获取随机字符串
            xml.append("</xml>");
            SortedMap<String,String> parameters = new TreeMap<String,String>();
            parameters.put("appid", WeChatConfigs.getAppID());//微信分配的公众账号ID
            parameters.put("mch_id", WeChatConfigs.getMchID());//商户号
            parameters.put("nonce_str", nonceStr);//随机字符串
            parameters.put("out_trade_no", out_trade_no);//商户订单号
            //parameters.put("transaction_id", transaction_id);//微信订单号
            parameters.put("out_refund_no", nonceStr);//商户退款单号
            parameters.put("fee_type", "CNY");//币总
            parameters.put("total_fee", total_fee);//订单金额
            parameters.put("refund_fee", total_fee);//退款金额
            parameters.put("op_user_id", WeChatConfigs.getMchID());//商户号
            parameters.put("sign", createSign(parameters, WeChatConfigs.getApiSecret()));//API密钥
            data = PayCommonUtil.getRequestXml(parameters);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            return null;
        }
        return data;
    }

    public  String createSign(SortedMap<String, String> packageParams, String AppKey) {
        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + AppKey);
        String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
        return sign;
    }

    @Override
    public Integer getPtOrderByExcel(List<PtOrder> listOrder) {
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet("拼团订单");
        HSSFRow row = sheet.createRow((int) 0);
        HSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        HSSFCell cell = row.createCell((short) 0);
        cell.setCellValue("订单编号");
        cell.setCellStyle(style);
        cell = row.createCell((short) 1);
        cell.setCellValue("快递配送信息");
        cell.setCellStyle(style);
        cell = row.createCell((short) 2);
        cell.setCellValue("联系方式");
        cell.setCellStyle(style);
        cell = row.createCell((short) 3);
        cell.setCellValue("联系人");
        cell.setCellStyle(style);
        cell = row.createCell((short) 4);
        cell.setCellValue("自提店铺");
        cell.setCellStyle(style);
        cell = row.createCell((short) 5);
        cell.setCellValue("下单时间");
        cell.setCellStyle(style);
        cell = row.createCell((short) 6);
        cell.setCellValue("订单状态");
        cell.setCellStyle(style);
        cell = row.createCell((short) 7);
        cell.setCellValue("拼团商品");
        cell.setCellStyle(style);
        for (int i = 0; i < listOrder.size(); i++) {
            row = sheet.createRow((int) i + 1);
            PtOrder ptOrder = listOrder.get(i);
            row.createCell((short) 0).setCellValue(ptOrder.getPtOrderCode());
            row.createCell((short) 1).setCellValue(ptOrder.getDeliveryAddress());
            row.createCell((short) 2).setCellValue(ptOrder.getContactMobile());
            row.createCell((short) 3).setCellValue(ptOrder.getContactPersion());
            row.createCell((short) 4).setCellValue(ptOrder.getShopName());
            row.createCell((short) 5).setCellValue(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(ptOrder.getUpdateTime()));
            if(ptOrder.getPtStatus().equals(1)){
                row.createCell((short) 6).setCellValue("已成团");
            }else if(ptOrder.getPtStatus().equals(2)){
                row.createCell((short) 6).setCellValue("待付款");
            }else if(ptOrder.getPtStatus().equals(3)){
                row.createCell((short) 6).setCellValue("未成团");
            }else if(ptOrder.getPtStatus().equals(4)){
                row.createCell((short) 6).setCellValue("待成团");
            }else if(ptOrder.getPtStatus().equals(5)){
                row.createCell((short) 6).setCellValue("已收货");
            }else if(ptOrder.getPtStatus().equals(6)){
                row.createCell((short) 6).setCellValue("已退款");
            }else if(ptOrder.getPtStatus().equals(7)){
                row.createCell((short) 6).setCellValue("已取消");
            }
            row.createCell((short) 7).setCellValue(ptGoodsDao.selectByPrimaryKey(ptOrder.getGoodId()).getPtGoodsName());
        }
        try {
            FileOutputStream fout = new FileOutputStream(getClass().getClassLoader().getResource("/").getPath()+new SimpleDateFormat("yyyyMMddhhmmss").format(new Date())+".xls");
            wb.write(fout);
            fout.close();
        } catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void downloadFile(HttpServletResponse response,boolean isDelete) {
        try {
            File file = new File(getClass().getClassLoader().getResource(new SimpleDateFormat("yyyyMMddhhmmss").format(new Date())+".xls").getPath());
            System.out.println("开始下载");
            if(!file.exists()){
                System.out.println("Have no such file!");
                return;
            }
            BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            response.reset();
            String fileName = URLEncoder.encode(file.getName(), "UTF-8");
            response.setContentType("application/octet-stream; charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
            if(isDelete)
            {
                file.delete();
            }
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    //退款，短信通知
    @Override
    public String sendMsgRefund(PtOrder ptOrder) {
        //获取用户的手机号
        Customer customer = customerDao.getCustomerById(ptOrder.getUserId());
        String str ="";
        if(customer != null){
            logger.info("发送短信开始，手机：{}", customer.getCustomerMobile());
            Map<String, String> map = new HashMap<String, String>();
            map.put("method", "sendMsg");
            map.put("username", "JSM40225");//此处填写用户账号
            map.put("password", "2z4jdhhr");//此处填写用户密码
            map.put("veryCode", "6ksjpzqkfiqu");
            map.put("mobile", customer.getCustomerMobile());//此处填写发送号码
            map.put("tempid", "JSM40225-0008");//此处填写模板短信编号
            map.put("content", "@1@=" + ptOrder.getPrice());//此处填写模板短信内容
            map.put("msgtype", "2");
            str = com.ibiaoke.common.utils.HttpPost.doPost("http://112.74.76.186:8030/service/httpService/httpInterface.do", map, "GBK");
            logger.info("发送短信结束，手机：{}，短信模板：{}，短信内容：{}。\n返回码:{}", customer.getCustomerMobile(), "JSM40225-0008", "好可惜，您的拼团队伍在24小时内人数未达标，您所支付的金额"+ptOrder.getPrice()+"元已原路返还", str);
            return str;
        }
        return str;
    }

    //支付宝退款
    @Override
    public String alipayRefundRequest(String out_trade_no,String trade_no,double refund_amount){
        String strResponse = null;
        try {
            AlipayClient alipayClient = new DefaultAlipayClient
                                  (AliPayConfigs.getGateWay(),
                                   AliPayConfigs.getAppID(),
                                   GlobalConfigs.getConfigure(GlobalConfigsKey.AliPay.PRIVATE_KEY),
                                   "json",
                                    "GBK",
                                    GlobalConfigs.getConfigure(GlobalConfigsKey.AliPay.ALI_PUBLIC_KEY),
                                   "RSA2");
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();

            request.setBizContent("{" +
                    "\"out_trade_no\":\"" + out_trade_no + "\"," +     //订单号
                    "\"trade_no\":\"" + trade_no + "\"," +             //交易号
                    "\"refund_amount\":\"" + refund_amount + "\"," +   //退款金额
                    "\"out_request_no\":\"" + ""+ "\"," +
                    "\"refund_reason\":\"正常退款\"" +
                    " }");

            AlipayTradeRefundResponse response;
            response = alipayClient.execute(request);
            if (response.isSuccess()) {
               List<PtOrder> ptOrderList = ptOrderDao.getPtOrderByCode(out_trade_no);
                //成功，更改订单状态
                ptOrderDao.upPtOrderStatus(ptOrderList.get(0).getPtOrderId(),6);
                //发送短信
                sendMsgRefund(ptOrderDao.GetPtOrderById(ptOrderList.get(0).getPtOrderId()));
                logger.info("支付宝退款成功，thanks！");
                strResponse="退款成功";
            }else {
                strResponse="退款失败";
            }
        } catch (Exception e) {
            logger.info("支付宝退款异常，请重试");
        }
        return strResponse;
    }

}
